/**
 * This program allows you to transmit data from OpenNI to a CORBA object
 * It may be used to send data threw network
 * @authors Romain CLEMENT, Alban FICHET, Aurelie MOIROUX
 */

/**
 * Includes
 */
#include <iostream>

// OpenNI lib
#include <XnOpenNI.h>
#include <XnCodecIDs.h>
#include <XnCppWrapper.h>

#include "CorbaSender.h"

/**
 * Defines
 */
#define XML_PATH "KinectConfig.xml"
#define CHECK_RC(nRetVal, what)                 \
  if (nRetVal != XN_STATUS_OK)                  \
  {                                             \
    printf("%s failed: %s\n", what, xnGetStatusString(nRetVal));\
    return nRetVal;                       \
  }

/**
 * Global vars
 */
CorbaSender* sender;
xn::Context g_Context;
xn::DepthGenerator g_DepthGenerator;
xn::UserGenerator g_UserGenerator;

XnBool g_bNeedPose = FALSE;
XnChar g_strPose[20] = "";
XnBool g_bDrawBackground = TRUE;
XnBool g_bDrawPixels = TRUE;
XnBool g_bDrawSkeleton = TRUE;
XnBool g_bPrintID = TRUE;
XnBool g_bPrintState = TRUE;
XnBool g_bPause = false;
XnBool g_bRecord = false;
XnBool g_bQuit = false;

/**
 * Callbacks
 */

// Callback: New user was detected
void XN_CALLBACK_TYPE User_NewUser(xn::UserGenerator& generator, XnUserID nId,
    void* pCookie) {
  printf("New User %d\n", nId);
  sender->newUserEvent(nId);
  // New user found
  if (g_bNeedPose) {
    g_UserGenerator.GetPoseDetectionCap().StartPoseDetection(g_strPose, nId);
  } else {
    g_UserGenerator.GetSkeletonCap().RequestCalibration(nId, TRUE);
  }
}

// Callback: An existing user was lost
void XN_CALLBACK_TYPE User_LostUser(xn::UserGenerator& generator, XnUserID nId,
    void* pCookie) {
  printf("Lost user %d\n", nId);
  sender->lostUserEvent(nId);
}

int main(int argc, char ** argv) {
  sender = new CorbaSender(argc, argv);

  /* Starting OpenNI session to send data */
  XnStatus nRetVal = XN_STATUS_OK;

  xn::EnumerationErrors errors;
  nRetVal = g_Context.InitFromXmlFile(XML_PATH, &errors);

  nRetVal = g_Context.FindExistingNode(XN_NODE_TYPE_DEPTH, g_DepthGenerator);
  CHECK_RC(nRetVal, "Find depth generator");
  nRetVal = g_Context.FindExistingNode(XN_NODE_TYPE_USER, g_UserGenerator);
  if (nRetVal != XN_STATUS_OK) {
    nRetVal = g_UserGenerator.Create(g_Context);
    CHECK_RC(nRetVal, "Find user generator");
  }

  XnCallbackHandle hUserCallbacks;

  g_UserGenerator.RegisterUserCallbacks(User_NewUser, User_LostUser, NULL,
      hUserCallbacks);

  nRetVal = g_Context.StartGeneratingAll();
  CHECK_RC(nRetVal, "StartGenerating");

  while (!g_bPause) {
     // Read next available data
     g_Context.WaitAndUpdateAll();
  }

  delete sender;

  return 0;
}
